package com.zeei.ems.meet.util;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.aliyuncvc.model.v20191030.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.zeei.ems.meet.model.MeetingContactVO;
import com.zeei.ems.meet.model.MeetingRecordDetailVO;
import com.zeei.ems.meet.model.dto.*;
import com.zeei.ems.meet.model.vo.MeetingParam;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Data
@Slf4j
@Component
public class MeetingUtil {
    private String regionId = "cn-hangzhou";
    private String endpoint = "aliyuncvc.cn-hangzhou.aliyuncs.com";

    @Value("${aliyun.meeting.accessKeyId:LTAI5tHpUJSaqKfC8FtwFGAk}")
    private String accessKeyId;

    @Value("${aliyun.meeting.secret:FJJsrt5ewKrJf1Zcd6P6Y9eBQCYIA2}")
    private String secret;

    static MeetingUtil meetingUtil;
    static IClientProfile profile;
    static IAcsClient client;

    @Autowired
    void setMeetingUtil(MeetingUtil meetingUtil) {
        MeetingUtil.meetingUtil = meetingUtil;

        MeetingUtil.profile = DefaultProfile.getProfile(this.getRegionId(), this.getAccessKeyId(), this.getSecret());
        MeetingUtil.client = new DefaultAcsClient(profile);
    }

    /**
     * 将用户信息批量同步给阿里会议系统
     * @param userList 用户列表
     * @return 返回是否同步成功
     */
    public static Boolean createUser(List<MeetingContactVO> userList) {
        try {
            if (!CollectionUtils.isEmpty(userList)) {
                //创建用户信息
                CreateUserRequest createUserRequest = new CreateUserRequest();
                //云视频API服务产品域名
                createUserRequest.setSysEndpoint(MeetingUtil.meetingUtil.getEndpoint());

                //设置请求参数
                List<GetUserResponse.UserInfo> list = new ArrayList();
                userList.forEach(user -> {
                    GetUserResponse.UserInfo userInfo = BeanMapperUtils.map(user, GetUserResponse.UserInfo.class);
                    userInfo.setGroupId(user.getAreaId());
                    userInfo.setGroupName(user.getAreaName());
                    list.add(userInfo);
                });

                String userInfoJson = JSON.toJSON(list).toString();
                createUserRequest.setUserInfo(userInfoJson);
                createUserRequest.setCount(list.size());

                //获取请求结果
                CreateUserResponse createUserResponse = MeetingUtil.client.getAcsResponse(createUserRequest);
                if (createUserResponse.getSuccess()) {
                    return Boolean.TRUE;
                }

                return Boolean.FALSE;
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.createUser, userList:", e);
        }

        return Boolean.FALSE;
    }

    /**
     * 将用户同步给阿里会议系统
     * @param user 用户信息
     * @return 返回是否同步成功
     */
    public static Boolean createUser(MeetingContactVO user){
        try {
            //创建用户信息
            CreateUserRequest createUserRequest = new CreateUserRequest();
            //云视频API服务产品域名（接口地址固定，无需修改）
            createUserRequest.setSysEndpoint(MeetingUtil.meetingUtil.getEndpoint());

            //设置请求参数
            List<GetUserResponse.UserInfo> list = new ArrayList();
            GetUserResponse.UserInfo userInfo = BeanMapperUtils.map(user, GetUserResponse.UserInfo.class);
            userInfo.setGroupId(user.getAreaId());
            userInfo.setGroupName(user.getAreaName());
            list.add(userInfo);
            String userInfoJson = JSON.toJSON(list).toString();
            createUserRequest.setUserInfo(userInfoJson);
            createUserRequest.setCount(1);
            //获取请求结果
            CreateUserResponse createUserResponse = MeetingUtil.client.getAcsResponse(createUserRequest);
            if (createUserResponse.getSuccess()) {
                return Boolean.TRUE;
            }

            return Boolean.FALSE;
        } catch (ClientException e) {
            log.error("MeetingUtil.createUser:", e);
        }

        return Boolean.FALSE;
    }

    /**
     * 根据用户ID获取用户信息
     * @param userId 用户ID
     * @return 返回用户信息
     */
    public static MeetingContactVO getUser(String userId){
        try {
            GetUserRequest getUserRequest = new GetUserRequest();
            getUserRequest.setUserId(userId);
            GetUserResponse getUserResponse = MeetingUtil.client.getAcsResponse(getUserRequest);
            if (getUserResponse.getSuccess()){
                return BeanMapperUtils.map(getUserResponse.getUserInfo(), MeetingContactVO.class);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getUser:", e);
        }

        return null;
    }

    /**
     * 获取所有用户信息
     * @param pageSize 每页大小
     * @param pageNumber 当前页
     * @return 返回用户信息，含分页信息
     */
    public static UserDto getUserList(Integer pageSize, Integer pageNumber){
        try {
            // 获取用户信息
            ListUsersRequest listUsersRequest = new ListUsersRequest();
            listUsersRequest.setPageNumber(pageNumber);
            listUsersRequest.setPageSize(pageSize);
            //云视频API服务产品域名
            listUsersRequest.setSysEndpoint(MeetingUtil.meetingUtil.getEndpoint());
            ListUsersResponse listUsersResponse = MeetingUtil.client.getAcsResponse(listUsersRequest);
            if (listUsersResponse.getSuccess()){
                UserDto userDto = BeanMapperUtils.map(listUsersResponse.getData(), UserDto.class);
                if (!CollectionUtils.isEmpty(listUsersResponse.getData().getUserInfos())){
                    List<MeetingContactVO> userList = new ArrayList<>();
                    listUsersResponse.getData().getUserInfos().forEach(userInfo->{
                        MeetingContactVO userVO = BeanMapperUtils.map(userInfo, MeetingContactVO.class);
                        userList.add(userVO);
                    });
                    userDto.setUserList(userList);
                }

                return userDto;
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getUserList:", e);
        }

        return null;
    }

    /**
     * 获取账户信息列表
     * @return 返回账户信息列表
     */
    public static AccountInfoDto getAccountInfo(){
        try {
            GetAccountInfoRequest getAccountInfoRequest = new GetAccountInfoRequest();
            GetAccountInfoResponse getAccountInfoResponse = client.getAcsResponse(getAccountInfoRequest);
            if (getAccountInfoResponse.getSuccess()){
                return BeanMapperUtils.map(getAccountInfoResponse.getAccountInfo(), AccountInfoDto.class);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getAccountInfo:", e);
        }

        return null;
    }

    /**
     * 删除账户信息
     * @param user 账户信息
     * @return 返回是否成功
     */
    public static Boolean deleteUser(MeetingContactVO user){
        try {
            // 删除用户
            DeleteUserRequest deleteUserRequest = new DeleteUserRequest();
            GetUserResponse.UserInfo deleteUserInfo = BeanMapperUtils.map(user, GetUserResponse.UserInfo.class);
            deleteUserRequest.setUserInfo(JSON.toJSONString(deleteUserInfo));
            deleteUserRequest.setCount(1);
            DeleteUserResponse deleteUserResponse = MeetingUtil.client.getAcsResponse(deleteUserRequest);
            if (deleteUserResponse.getSuccess()){
                return Boolean.TRUE;
            }

            return Boolean.FALSE;
        } catch (ClientException e) {
            log.error("MeetingUtil.deleteUser:", e);
        }

        return Boolean.FALSE;
    }

    /**
     * 删除账户列表信息
     * @param userList 账户信息列表
     * @return 返回是否成功
     */
    public static Boolean deleteUser(List<MeetingContactVO> userList){
        if (!CollectionUtils.isEmpty(userList)){
            userList.forEach(meetingContact -> {
                deleteUser(meetingContact);
            });
        }

        return Boolean.FALSE;
    }

    /**
     * 创建会议，调用阿里会议创建接口和检查会议接口，返回会议信息
     * @param meeting 会议实体
     * @return 返回会议信息
     */
    public static MeetingDto createMeeting(MeetingParam meeting) {
        try {
            CreateMeetingRequest createMeetingRequest = BeanMapperUtils.map(meeting, CreateMeetingRequest.class);
            CreateMeetingResponse createMeetingResponse = MeetingUtil.client.getAcsResponse(createMeetingRequest);
            if (createMeetingResponse.getSuccess()) {
                return getMeeting(createMeetingResponse.getMeetingInfo().getMeetingUUID());
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.createMeeting:", e);
        }

        return null;
    }

    /**
     * 获取会议信息
     * @param meetingUUID 会议UUID编码
     * @return 返回会议信息
     */
    public static MeetingDto getMeeting(String meetingUUID) {
        try {
            // 获取会议信息
            GetMeetingRequest getMeetingRequest = new GetMeetingRequest();
            getMeetingRequest.setMeetingUUID(meetingUUID);
            GetMeetingResponse getMeetingResponse = MeetingUtil.client.getAcsResponse(getMeetingRequest);
            if (getMeetingResponse.getSuccess()) {
                return BeanMapperUtils.map(getMeetingResponse.getMeetingInfo(), MeetingDto.class);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getMeeting:", e);
        }

        return null;
    }

    /**
     * 加入会议
     * @param userId 加入用户ID
     * @param meetingCode 会议编码
     * @param meetingPassword 创建会议设置的密码
     * @return 返回会议成员信息
     */
    public static MemberDto joinMeeting(String userId, String meetingCode, String meetingPassword) {
        try {
            // 加入会议
            JoinMeetingRequest joinMeetingRequest = new JoinMeetingRequest();
            joinMeetingRequest.setUserId(userId);
            joinMeetingRequest.setMeetingCode(meetingCode);
            joinMeetingRequest.setPassword(meetingPassword);
            JoinMeetingResponse joinMeetingResponse = MeetingUtil.client.getAcsResponse(joinMeetingRequest);
            if (joinMeetingResponse.getSuccess()) {
                return BeanMapperUtils.map(joinMeetingResponse.getMeetingInfo(), MemberDto.class);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.joinMeeting:", e);
        }

        return null;
    }

    /**
     * 激活会议
     * @param meetingCode 会议编码
     * @param meetingUUID 会议UUID编码
     * @return 返回会议信息
     */
    public static MeetingDto activeMeeting(String meetingCode, String meetingUUID) {
        try {
            //激活会议口令
            ActiveMeetingRequest activeMeetingRequest = new ActiveMeetingRequest();
            activeMeetingRequest.setMeetingUUID(meetingUUID);
            activeMeetingRequest.setMeetingCode(meetingCode);
            ActiveMeetingResponse activeMeetingResponse = MeetingUtil.client.getAcsResponse(activeMeetingRequest);
            if (activeMeetingResponse.getSuccess()) {
                return BeanMapperUtils.map(activeMeetingResponse.getMeetingInfo(), MeetingDto.class);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.activeMeeting:", e);
        }

        return null;
    }

    /**
     * 删除会议，成功返回true，失败返回false
     * @param meetingUUID 会议UUID编码
     * @return 成功返回true，失败返回false
     */
    public static Boolean deleteMeeting(String meetingUUID) {
        try {
            // 删除会议
            DeleteMeetingRequest deleteMeetingRequest = new DeleteMeetingRequest();
            deleteMeetingRequest.setMeetingUUID(meetingUUID);
            DeleteMeetingResponse deleteMeetingResponse = MeetingUtil.client.getAcsResponse(deleteMeetingRequest);
            if (deleteMeetingResponse.getSuccess()) {
                return Boolean.TRUE;
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.deleteMeeting:", e);
        }

        return Boolean.FALSE;
    }

    /**
     * 获取参会人数，返回参会人员数值，如无人参会返回0，报错返回-1
     * @param meetingUUID 会议UUID编码
     * @return 返回参会人员数值，如无人参会返回0，报错返回-1
     */
    public static Integer getMeetingNumber(String meetingUUID){
        try {
            // 获取会议成员
            GetMeetingMemberRequest getMeetingMemberRequest = new GetMeetingMemberRequest();
            getMeetingMemberRequest.setMeetingUUID(meetingUUID);
            GetMeetingMemberResponse getMeetingMemberResponse = MeetingUtil.client.getAcsResponse(getMeetingMemberRequest);
            if (getMeetingMemberResponse.getSuccess()){
                return (Integer)getMeetingMemberResponse.getMembers().get(meetingUUID);
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getMeetingNumber:", e);
            return -1;
        }

        return 0;
    }

    /**
     * 获取参会人数，返回参会人员数值，如无人参会返回0，报错返回-1
     * @param meetingUUID 会议UUID编码
     * @return 返回参会人员数值，如无人参会返回0，报错返回-1
     */
    public static MeetingDto getMeetingListMembers(String meetingUUID){
        try {
            // 获取会议成员
            ListMembersRequest listMembersRequest = new ListMembersRequest();
            listMembersRequest.setMeetingUUID(meetingUUID);
            ListMembersResponse listMembersResponse = MeetingUtil.client.getAcsResponse(listMembersRequest);
            if (listMembersResponse.getSuccess()){
                MeetingDto meetingDto = BeanMapperUtils.map(listMembersResponse.getMeetingInfo(), MeetingDto.class);
                List<ListMembersResponse.MeetingInfo.MemberRecord> memberInfoList = listMembersResponse.getMeetingInfo().getMemberInfos();
                if (!CollectionUtils.isEmpty(memberInfoList)){
                    List<MeetingRecordDetailVO> memberRecordDetailList = new ArrayList<>();
                    memberInfoList.forEach(memberRecord -> {
                        memberRecordDetailList.add(BeanMapperUtils.map(memberRecord, MeetingRecordDetailVO.class));
                    });
                    meetingDto.setMemberList(memberRecordDetailList);
                }
            }
        } catch (ClientException e) {
            log.error("MeetingUtil.getMeetingNumber:", e);
        }

        return null;
    }
}
